package panda.query.tree;

import panda.file.Page;
import panda.query.scan.PartitionProductScanner;
import panda.query.scan.Scanner;
import panda.query.struct.Attribute;
import panda.query.util.TempTable;
import panda.record.Schema;
import panda.record.TableToken;
import panda.server.Panda;
import panda.transaction.Transaction;

/**
 * 
 * @author Tian Yuan
 *
 */
public class PartitionProductNode implements QueryTreeNode{
	private QueryTreeNode l, r;
	private Schema sch = new Schema();
	private Transaction tx;
	
	public PartitionProductNode(QueryTreeNode l, QueryTreeNode r, Transaction tx) {
		this.l = l;
		this.r = r;
		this.tx = tx;
		sch.addAll(l.getSchema());
		sch.addAll(r.getSchema());
	}

	public Scanner open() {
		TempTable tt = new TempTable(r.getSchema(), tx);
		tt.copyFrom(r.open());
		return new PartitionProductScanner(l.open(), tt.getTableInfo(), tx);
	}

	public int distinctSize(Attribute attr) {
		if (l.getSchema().hasAttribute(attr))
			return l.distinctSize(attr);
		else
			return r.distinctSize(attr);
	}

	public Schema getSchema() {
		return sch;
	}

	public int blockAccessed() {
		int avail = Panda.getBufferManager().available();
		double t = (double)Page.BLOCK_SIZE / TableToken.getTupleLength(r.getSchema());
		int m = (int)(Math.ceil(r.outputSize() / t));
		int num = m / avail;
		
		return r.blockAccessed() + (l.blockAccessed() * num);
	}
	
	public int outputSize() {
		return l.outputSize() * r.outputSize();
	}

}
